#ifndef __INTEGRAL__
#define __INTEGRAL__

#include <inttypes.h>

#include "bit-field.h"

template<typename T>
class Integral : public BitField<T>
{
public:
  Integral () { }

  Integral (T value)
  {
    this->_field = value;
  }

  Integral (const BitField<T>& field)
  {
    this->_field = field;
  }

  const Integral<T>& operator= (T value)
  {
    this->_field = value;
    return *this;
  }

  const Integral<T>& operator= (const BitField<T>& field)
  {
    this->_field = field;
    return *this;
  }

  const Integral<T>& operator+= (T value)
  {
    this->_field += value;
    return *this;
  }

  const Integral<T>& operator-= (T value)
  {
    this->_field -= value;
    return *this;
  }

  const Integral<T>& operator*= (T value)
  {
    this->_field *= value;
    return *this;
  }

  const Integral<T>& operator/= (T value)
  {
    this->_field /= value;
    return *this;
  }

  const Integral<T>& operator++ ()
  {
    ++this->_field;
    return *this;
  }

  const Integral<T> operator++ (int)
  {
    Integral<T> ret = *this;
    ++this->_field;
    return ret;
  }

  const Integral<T>& operator-- ()
  {
    --this->_field;
    return *this;
  }

  const Integral<T> operator-- (int)
  {
    Integral<T> ret = *this;
    --this->_field;
    return ret;
  }

  /* Since BitField can typecast to type T all of the non-assignment
   * arithmetic can be taken care of via the built-in type arithmetic */
};

typedef Integral<int32_t> Int32;
typedef Integral<uint32_t> UInt32;
typedef Integral<int16_t> Int16;
typedef Integral<uint16_t> UInt16;
typedef Integral<int8_t> Int8;
typedef Integral<uint8_t> UInt8;

#endif /* __INTEGRAL__ */
